home *** CD-ROM | disk | FTP | other *** search
- /* EIGENLINE: function performs eigenvector fit to data points and
- * yields slope and intercept of line
- * line = eigenline (pt, n, &m, &b)
- * If line=0, then fit has not been performed due to 1-pixel line.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- #include <images.h> /* for sun images */
-
- #define INFINITY 1000000.0 /* infinity slope value */
-
- short
- eigenline (pt, n, m, b)
- struct point *pt; /* input set of coordinate points */
- long n; /* number of input points */
- double *m, *b; /* slope and intercept of line */
-
- {
- struct dpoint *data; /* floating point data vector */
- struct dpoint ptAvg; /* average of data points */
- double a11, a12, a21, a22; /* matrix elements */
- double temp; /* temporary variable */
- double lambda1; /* minimum eigenvalue */
- long i;
-
- /* check 1-point "line" */
- if (n == 0)
- return (0);
-
- /* allocate floating point vector for data */
- if ((data = (struct dpoint *) calloc (n, sizeof (struct dpoint))) == NULL) {
- printf ("EIGENLINE: not enough memory -- sorry");
- return (-1);
- }
- for (i = 0; i < n; i++) {
- data[i].x = (double) pt[i].x;
- data[i].y = (double) pt[i].y;
- }
-
- /* calculate average and translate each point by the average to around (0,0) */
- ptAvg.x = ptAvg.y = 0.0;
- for (i = 0; i < n; i++) {
- ptAvg.x += data[i].x;
- ptAvg.y += data[i].y;
- }
- ptAvg.x /= (double) n;
- ptAvg.y /= (double) n;
- for (i = 0; i < n; i++) {
- data[i].x -= ptAvg.x;
- data[i].y -= ptAvg.y;
- }
-
- /* determine matrix */
- a11 = a12 = a21 = a22 = 0;
- for (i = 0; i < n; i++) {
- a11 += data[i].x * data[i].x;
- a12 = a21 += data[i].x * data[i].y;
- a22 += data[i].y * data[i].y;
- }
-
- /* determine minimum eigenvalue */
- temp = (a11 + a22);
- lambda1 = (temp - sqrt (temp * temp - 4.0 * a11 * a22 + 4.0 * a12 * a12))
- / 2.0;
-
- /* calculate slope and intercept */
- if (a11 == lambda1)
- *m = INFINITY;
- else
- *m = -a12 / (lambda1 - a11);
- *b = ptAvg.y - *m * ptAvg.x;
-
- return (1);
- }
-